@@ -18,6 +18,11 @@ module LiquidDroppable |
||
| 18 | 18 |
yield [name, __send__(name)] |
| 19 | 19 |
} |
| 20 | 20 |
end |
| 21 |
+ |
|
| 22 |
+ def as_json |
|
| 23 |
+ return {} unless defined?(self.class::METHODS)
|
|
| 24 |
+ Hash[self.class::METHODS.map { |m| [m, send(m).as_json]}]
|
|
| 25 |
+ end |
|
| 21 | 26 |
end |
| 22 | 27 |
|
| 23 | 28 |
included do |
@@ -33,12 +38,10 @@ module LiquidDroppable |
||
| 33 | 38 |
self.class::Drop.new(self) |
| 34 | 39 |
end |
| 35 | 40 |
|
| 36 |
- class MatchDataDrop < Liquid::Drop |
|
| 37 |
- def initialize(object) |
|
| 38 |
- @object = object |
|
| 39 |
- end |
|
| 41 |
+ class MatchDataDrop < Drop |
|
| 42 |
+ METHODS = %w[pre_match post_match names size] |
|
| 40 | 43 |
|
| 41 |
- %w[pre_match post_match names size].each { |attr|
|
|
| 44 |
+ METHODS.each { |attr|
|
|
| 42 | 45 |
define_method(attr) {
|
| 43 | 46 |
@object.__send__(attr) |
| 44 | 47 |
} |
@@ -64,7 +67,9 @@ module LiquidDroppable |
||
| 64 | 67 |
require 'uri' |
| 65 | 68 |
|
| 66 | 69 |
class URIDrop < Drop |
| 67 |
- URI::Generic::COMPONENT.each { |attr|
|
|
| 70 |
+ METHODS = URI::Generic::COMPONENT |
|
| 71 |
+ |
|
| 72 |
+ METHODS.each { |attr|
|
|
| 68 | 73 |
define_method(attr) {
|
| 69 | 74 |
@object.__send__(attr) |
| 70 | 75 |
} |
@@ -92,7 +92,9 @@ module LiquidInterpolatable |
||
| 92 | 92 |
|
| 93 | 93 |
def interpolate_string(string, self_object = nil) |
| 94 | 94 |
interpolate_with(self_object) do |
| 95 |
- Liquid::Template.parse(string).render!(interpolation_context) |
|
| 95 |
+ catch :as_object do |
|
| 96 |
+ Liquid::Template.parse(string).render!(interpolation_context) |
|
| 97 |
+ end |
|
| 96 | 98 |
end |
| 97 | 99 |
end |
| 98 | 100 |
|
@@ -225,6 +227,25 @@ module LiquidInterpolatable |
||
| 225 | 227 |
JSON.dump(input) |
| 226 | 228 |
end |
| 227 | 229 |
|
| 230 |
+ # Returns a Ruby object |
|
| 231 |
+ # |
|
| 232 |
+ # It can be used as a JSONPath replacement for Agents that only support Liquid: |
|
| 233 |
+ # |
|
| 234 |
+ # Event: {"something": {"nested": {"data": 1}}}
|
|
| 235 |
+ # Liquid: {{something.nested | as_object}}
|
|
| 236 |
+ # Returns: {"data": 1}
|
|
| 237 |
+ # |
|
| 238 |
+ # Splitting up a string with Liquid filters and return the Array: |
|
| 239 |
+ # |
|
| 240 |
+ # Event: {"data": "A,B,C"}}
|
|
| 241 |
+ # Liquid: {{data | split: ',' | as_object}}
|
|
| 242 |
+ # Returns: ['A', 'B', 'C'] |
|
| 243 |
+ # |
|
| 244 |
+ # as_object ALWAYS has be the last filter in a Liquid expression! |
|
| 245 |
+ def as_object(object) |
|
| 246 |
+ throw :as_object, object.as_json |
|
| 247 |
+ end |
|
| 248 |
+ |
|
| 228 | 249 |
private |
| 229 | 250 |
|
| 230 | 251 |
def logger |
@@ -443,7 +443,7 @@ class AgentDrop |
||
| 443 | 443 |
@object.short_type |
| 444 | 444 |
end |
| 445 | 445 |
|
| 446 |
- [ |
|
| 446 |
+ METHODS = [ |
|
| 447 | 447 |
:name, |
| 448 | 448 |
:type, |
| 449 | 449 |
:options, |
@@ -456,7 +456,9 @@ class AgentDrop |
||
| 456 | 456 |
:disabled, |
| 457 | 457 |
:keep_events_for, |
| 458 | 458 |
:propagate_immediately, |
| 459 |
- ].each { |attr|
|
|
| 459 |
+ ] |
|
| 460 |
+ |
|
| 461 |
+ METHODS.each { |attr|
|
|
| 460 | 462 |
define_method(attr) {
|
| 461 | 463 |
@object.__send__(attr) |
| 462 | 464 |
} unless method_defined?(attr) |
@@ -119,4 +119,8 @@ class EventDrop |
||
| 119 | 119 |
def _location_ |
| 120 | 120 |
@object.location |
| 121 | 121 |
end |
| 122 |
+ |
|
| 123 |
+ def as_json |
|
| 124 |
+ {location: _location_.as_json, agent: @object.agent.to_liquid.as_json, payload: @payload.as_json, created_at: created_at.as_json}
|
|
| 125 |
+ end |
|
| 122 | 126 |
end |
@@ -264,4 +264,59 @@ describe LiquidInterpolatable::Filters do |
||
| 264 | 264 |
expect(agent.interpolated['cleaned']).to eq('FOObar ZOObar')
|
| 265 | 265 |
end |
| 266 | 266 |
end |
| 267 |
+ |
|
| 268 |
+ context 'as_object' do |
|
| 269 |
+ let(:agent) { Agents::InterpolatableAgent.new(name: "test") }
|
|
| 270 |
+ |
|
| 271 |
+ it 'returns an array that was splitted in liquid tags' do |
|
| 272 |
+ agent.interpolation_context['something'] = 'test,string,abc' |
|
| 273 |
+ agent.options['array'] = "{{something | split: ',' | as_object}}"
|
|
| 274 |
+ expect(agent.interpolated['array']).to eq(['test', 'string', 'abc']) |
|
| 275 |
+ end |
|
| 276 |
+ |
|
| 277 |
+ it 'returns an object that was not modified in liquid' do |
|
| 278 |
+ agent.interpolation_context['something'] = {'nested' => {'abc' => 'test'}}
|
|
| 279 |
+ agent.options['object'] = "{{something.nested | as_object}}"
|
|
| 280 |
+ expect(agent.interpolated['object']).to eq({"abc" => 'test'})
|
|
| 281 |
+ end |
|
| 282 |
+ |
|
| 283 |
+ context 'as_json' do |
|
| 284 |
+ def ensure_safety(obj) |
|
| 285 |
+ JSON.parse(JSON.dump(obj)) |
|
| 286 |
+ end |
|
| 287 |
+ |
|
| 288 |
+ it 'it converts "complex" objects' do |
|
| 289 |
+ agent.interpolation_context['something'] = {'nested' => Service.new}
|
|
| 290 |
+ agent.options['object'] = "{{something | as_object}}"
|
|
| 291 |
+ expect(agent.interpolated['object']).to eq({'nested'=> ensure_safety(Service.new.as_json)})
|
|
| 292 |
+ end |
|
| 293 |
+ |
|
| 294 |
+ it 'works with AgentDrops' do |
|
| 295 |
+ agent.interpolation_context['something'] = agent |
|
| 296 |
+ agent.options['object'] = "{{something | as_object}}"
|
|
| 297 |
+ expect(agent.interpolated['object']).to eq(ensure_safety(agent.to_liquid.as_json.stringify_keys)) |
|
| 298 |
+ end |
|
| 299 |
+ |
|
| 300 |
+ it 'works with EventDrops' do |
|
| 301 |
+ event = Event.new(payload: {some: 'payload'}, agent: agent, created_at: Time.now)
|
|
| 302 |
+ agent.interpolation_context['something'] = event |
|
| 303 |
+ agent.options['object'] = "{{something | as_object}}"
|
|
| 304 |
+ expect(agent.interpolated['object']).to eq(ensure_safety(event.to_liquid.as_json.stringify_keys)) |
|
| 305 |
+ end |
|
| 306 |
+ |
|
| 307 |
+ it 'works with MatchDataDrops' do |
|
| 308 |
+ match = "test string".match(/\A(?<word>\w+)\s(.+?)\z/) |
|
| 309 |
+ agent.interpolation_context['something'] = match |
|
| 310 |
+ agent.options['object'] = "{{something | as_object}}"
|
|
| 311 |
+ expect(agent.interpolated['object']).to eq(ensure_safety(match.to_liquid.as_json.stringify_keys)) |
|
| 312 |
+ end |
|
| 313 |
+ |
|
| 314 |
+ it 'works with URIDrops' do |
|
| 315 |
+ uri = URI.parse("https://google.com?q=test")
|
|
| 316 |
+ agent.interpolation_context['something'] = uri |
|
| 317 |
+ agent.options['object'] = "{{something | as_object}}"
|
|
| 318 |
+ expect(agent.interpolated['object']).to eq(ensure_safety(uri.to_liquid.as_json.stringify_keys)) |
|
| 319 |
+ end |
|
| 320 |
+ end |
|
| 321 |
+ end |
|
| 267 | 322 |
end |